#include "lm75a.h"

static int lm75a_write16(lm75a_t *obj, uint8_t reg, uint16_t value) {
    t_i2c_start(obj->i2c);
    t_i2c_send_byte(obj->i2c, (obj->dev_addr << 1) | 0);
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -1; }

    t_i2c_send_byte(obj->i2c, reg);
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -2; }

    t_i2c_send_byte(obj->i2c, (uint8_t)(value >> 8));
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -3; }

    t_i2c_send_byte(obj->i2c, (uint8_t)(value & 0xFF));
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -4; }

    t_i2c_stop(obj->i2c);
    return 0;
}

static int lm75a_read16(lm75a_t *obj, uint8_t reg, uint16_t *value) {
    t_i2c_start(obj->i2c);
    t_i2c_send_byte(obj->i2c, (obj->dev_addr << 1) | 0);
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -1; }

    t_i2c_send_byte(obj->i2c, reg);
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -2; }

    t_i2c_start(obj->i2c);
    t_i2c_send_byte(obj->i2c, (obj->dev_addr << 1) | 1);
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -3; }

    uint8_t msb = t_i2c_read_byte(obj->i2c, 1);
    uint8_t lsb = t_i2c_read_byte(obj->i2c, 0);
    t_i2c_stop(obj->i2c);

    *value = (msb << 8) | lsb;
    return 0;
}

void lm75a_init(lm75a_t *obj, t_i2c_t *i2c, uint8_t addr) {
    obj->i2c = i2c;
    obj->dev_addr = addr & 0x7F;
}


int lm75a_read_temp_0P125(lm75a_t *obj, float *out_temp) {
    uint16_t raw;
    if (lm75a_read16(obj, 0x00, &raw) != 0)
        return -1;

    // 右移5位，保留前11位
    int16_t temp_raw = (int16_t)(raw >> 5);

    // 如果是负数，补符号位（11位扩展到16位）
    if (temp_raw & 0x0400) {
        temp_raw |= 0xF800;  // 扩展符号（保留11位的补码）
    }

    *out_temp = temp_raw * 0.125f;
    return 0;
}


int lm75a_write_config(lm75a_t *obj, uint8_t config) {
    t_i2c_start(obj->i2c);
    t_i2c_send_byte(obj->i2c, (obj->dev_addr << 1) | 0);
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -1; }

    t_i2c_send_byte(obj->i2c, 0x01);  // 配置寄存器地址
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -2; }

    t_i2c_send_byte(obj->i2c, config);
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -3; }

    t_i2c_stop(obj->i2c);
    return 0;
}

int lm75a_read_config(lm75a_t *obj, uint8_t *config) {
    t_i2c_start(obj->i2c);
    t_i2c_send_byte(obj->i2c, (obj->dev_addr << 1) | 0);
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -1; }

    t_i2c_send_byte(obj->i2c, 0x01);
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -2; }

    t_i2c_start(obj->i2c);
    t_i2c_send_byte(obj->i2c, (obj->dev_addr << 1) | 1);
    if (t_i2c_wait_ack(obj->i2c)) { t_i2c_stop(obj->i2c); return -3; }

    *config = t_i2c_read_byte(obj->i2c, 0);
    t_i2c_stop(obj->i2c);
    return 0;
}

// 设定 THYST 与 TOS 阈值（摄氏度）
static int lm75a_set_threshold(lm75a_t *obj, uint8_t reg, float temp) {
    int16_t raw = (int16_t)(temp / 0.125f);        // 转换为11位值（单位数）
    uint16_t value = ((uint16_t)(raw & 0x07FF)) << 5;  // 保留11位，左移5位填入寄存器格式
    return lm75a_write16(obj, reg, value);
}

int lm75a_set_thyst(lm75a_t *obj, float temp) {
    return lm75a_set_threshold(obj, 0x02, temp);
}

int lm75a_set_tos(lm75a_t *obj, float temp) {
    return lm75a_set_threshold(obj, 0x03, temp);
}

// 读取 TOS 与 THYST 阈值
static int lm75a_get_threshold(lm75a_t *obj, uint8_t reg, float *temp) {
    uint16_t raw;
    if (lm75a_read16(obj, reg, &raw) != 0) return -1;

    int16_t val = (int16_t)(raw >> 5);         // 提取11位有效数据
    if (val & 0x0400) val |= 0xF800;           // 符号扩展：若为负数（D10=1）

    *temp = val * 0.125f;
    return 0;
}
int lm75a_get_thyst(lm75a_t *obj, float *temp) {
    return lm75a_get_threshold(obj, 0x02, temp);
}

int lm75a_get_tos(lm75a_t *obj, float *temp) {
    return lm75a_get_threshold(obj, 0x03, temp);
}
